/**
 * @file main.cpp
 * @author Ruiming Guo (guoruiming@stu.scu.edu.cn)
 * @brief 给定一颗 n 个点的有根树，边有边权，节点从 1 至 n 编号，1
 * 号节点是这棵树的根。 再给出一个参数 t，对于树上的每个节点 u，请求出 u
 * 的子树中有多少节点满足该节点到 u 的距离不大于 t。
 * @version 0.1
 * @date 2022-04-29
 *
 * @copyright Copyright (c) 2022
 *
 */

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 200005;
int n;
ll m;
int cnt, head[N];
struct node {
  int to, next;
} e[N];
// 以上 链式前向星
int idx;
int poi[N];    // dfs欧拉序列
int f[N][23];  // f[i][j]: 第i个结点向上跳2^j个结点后到达的结点
ll dis[N];     // 距离
int dlt[N];    // 答案
void add(int u, int v) {
  e[++cnt] = {v, head[u]};
  head[u] = cnt;
}
int find(int x) {
  int now = x;
  for (int j = 20; j >= 0; --j)
    if (dis[x] - dis[f[now][j]] <= m) now = f[now][j];
  return f[now][0];
}
void dfs(int x) {
  idx++;         // 时间戳
  poi[idx] = x;  // 欧拉序列
  for (int i = head[x]; i; i = e[i].next) dfs(e[i].to);
}
int main() {
  scanf("%d%lld", &n, &m);
  dlt[1] = 1;
  // 对每个节点
  for (int i = 2; i <= n; ++i) {
    int x;
    ll w;
    scanf("%d%lld", &x, &w);
    add(x, i);
    // 边权化为点权
    f[i][0] = x;
    dis[i] = dis[x] + w;
    // 为了代码清楚把初始化fa数组放到dfs前边了
    // for (int j = 1; j <= 20; ++j) f[i][j] = f[f[i][j - 1]][j - 1];
    // 树上差分
    dlt[i]++;
    dlt[find(i)]--;
  }

  // 这行跟数据没关系，就是在建立fa倍增数组
  for (int i = 2; i <= n; ++i)
    for (int j = 1; j <= 20; ++j) f[i][j] = f[f[i][j - 1]][j - 1];

  dfs(1);

  // 将统计子树中合法节点的个数(top-down)，改为从每个节点，将合法的祖先节点加上1(bottom-up)
  for (int i = n; i; i--) dlt[f[poi[i]][0]] += dlt[poi[i]];
  for (int i = 1; i <= n; ++i) printf("%d\n", dlt[i]);
  return 0;
}
